
/****************************************************************************/

int kernelMultitaskerGetProcessState(int processId, processState *state)
{
	int status = 0;
	kernelProcess *theProcess;

	if (!multitaskingEnabled)
		return (status = ERR_NOTINITIALIZED);

	// Make sure the kernelProcessState pointer we were given is legal
	if (state == NULL)
		return (status = ERR_NULLPARAMETER);

	ACQUIRE_LOCK_PROCESS_QUEUE();

	theProcess = getProcessById(processId);

	if (theProcess == NULL)
	{
		RELEASE_LOCK_PROCESS_QUEUE();
		return (status = ERR_NOSUCHPROCESS);
	}

	*state = theProcess->state;

	RELEASE_LOCK_PROCESS_QUEUE();

	return (status = 0);
}

/****************************************************************************/

int kernelMultitaskerSetProcessState(int processId, processState newState)
{
	int status = 0;
	kernelProcess *changeProcess;

	if (!multitaskingEnabled)
		return (status = ERR_NOTINITIALIZED);

	ACQUIRE_LOCK_PROCESS_QUEUE();

	changeProcess = getProcessById(processId);

	if (changeProcess == NULL)
	{
		RELEASE_LOCK_PROCESS_QUEUE();
		return (status = ERR_NOSUCHPROCESS);
	}

	// Permission check.  A privileged process can change the state of any 
	// other process, but a non-privileged process can only change the state 
	// of processes owned by the same user
	if (kernelCurrentProcess->privilege != PRIVILEGE_SUPERVISOR)
	{
		if (kernelCurrentProcess->userId != changeProcess->userId)
		{
			RELEASE_LOCK_PROCESS_QUEUE();
			return (status = ERR_PERMISSION);
		}
	}

	// Make sure the new state is a legal one and set the state value of the process
	status = ERR_INVALID;
	if (newState == proc_ready || newState == proc_sleeping)
	{
		if (changeProcess->state == proc_stopped || changeProcess->state == proc_ready)
		{
			changeProcess->state = newState;
			status = 0;
		}
		else if (changeProcess->state == proc_running)
		{
			if (newState == proc_sleeping)
			{
				changeProcess->state = newState;
				kernelMultitaskerDispatch(DISPATCH_RESCHEDULE);
				status = 0;
			}
		}
	}

	RELEASE_LOCK_PROCESS_QUEUE();

	return (status);
}

/****************************************************************************/

int kernelMultitaskerProcessIsAlive(int processId)
{
	// Returns 1 if a process exists and has not finished (or been terminated)

	int status = 0;

	kernelProcess *targetProcess = NULL;

	if (!multitaskingEnabled)
		return (status = 0);

	ACQUIRE_LOCK_PROCESS_QUEUE();

	targetProcess = getProcessById(processId);

	if (targetProcess && (targetProcess->state != proc_finished) && (targetProcess->state != proc_zombie))
		status = 1;
	else
		status = 0;

	RELEASE_LOCK_PROCESS_QUEUE();
	return (status);
}

/****************************************************************************/

int kernelMultitaskerGetProcessorTime(clock_t *clk)
{
	// Returns processor time used by a process since its start.

	int status = 0;

	if (!multitaskingEnabled)
		return (status = ERR_NOTINITIALIZED);

	if (clk == NULL)
		return (status = ERR_NULLPARAMETER);

	*clk = kernelCurrentProcess->cpuTime;

	return (status = 0);
}

/****************************************************************************/

